﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace eSSP_example.Cpi
{
    public class ClsApiClass
    {
        //  OpenApi
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern int openApi();

        //  closeApi
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern int closeApi();

        //  getConnectionStatus
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int getConnectionStatus(ref byte pu8IsOnline);

        //  dispenseAmount
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int dispenseAmount(int u32Amount);

        //  dispenseFromHoppers
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int dispenseFromHoppers(byte[] u8NumbersOfCoins);

        //  emptyHoppers - Empty one or more hoppers
        /// Empties one or more Hopper(s). 
        /// When a Hopper is physically empty, it will send a "Coin Eject Timeout" event.
        /// If more coins were inside than expected, inventory will be set to zero
        /// at the end of the operation. <summary>
        /// Empties one or more Hopper(s). 
        ///     u8Hoppers   One bit for every hopper to empty          
        ///                 Set the corresponding bits to 1 to empty   
        ///                 the Hopper,0 to not empty the Hopper.      
        ///                 Bit 0 = Hopper 1                         
        ///                 Bit 1 = Hopper 2                         
        ///                 Bit 2 = Hopper 3                         
        ///                     ...
        ///                 Bit 7 = Hopper 8
        /// \retval     Asynchronous request identificationID
        /// </summary>
        /// <param name="u8Hoppers"></param>
        /// <returns></returns>
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int emptyHoppers(byte u8Hoppers);

        /// <summary>
        ///     getAmountDispensed
        /// </summary>
        /// <param name="pu32Amount"></param>
        /// <returns></returns>
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int getAmountDispensed(ref int pu32Amount);

        /// <summary>
        ///     acceptAmount
        /// </summary>

        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int acceptAmount(int u32Amount);

        //  endAcception
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int endAcception();

        //  Get amount accepted
        //  getAmountAccepted
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int getAmountAccepted(ref int pAmount);

        //  Restart Device
        //  restartDevice
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int restartDevice();

        //  getFirmwareVersions
        [DllImport("ClsApi.dll")]
        private static extern int getFirmwareVersions(byte[] pc8VersionStrings);

        //  getDenominationFromHopperNo
        //[DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        //private static extern int getDenominationFromHopperNo(
        //    byte u8HopperNo, byte[] pc8ISO, unsigned short[] pu16Denom, char* pc8Mint);

        //  pollSystemEvents
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int pollSystemEvents(ref short pu16NumberOfNewEvents, int[] pu16Events);

        //  pollAcceptorEvents
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int pollAcceptorEvents(ref short pu16NumberOfNewEvents, int[] pu16Events);

        //  pollApiEvents
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int pollApiEvents(ref short pu16NumberOfNewEvents, int[] pu32Events);

        //  pollDispenserEvents
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int pollDispenserEvents(ref short pu16NumberOfNewEvents, int[] pu16Events);

        //  getOnlineHoppers
        //  T_ApiResult API_EXPORT getOnlineHoppers(uint8_t *pu8HoppersOnline);
        [DllImport("ClsApi.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern int getOnlineHoppers(ref byte pu8HoppersOnline);

        //    T_ApiResult API_EXPORT getFullSerialNumber(char * const pc8String, int maxLength);
        [DllImport("ClsApi.dll")]
        private static extern int getFullSerialNumber(byte[] pc8String, int maxLength);

        //    T_ApiResult API_EXPORT getSerialNumber(char * const pc8String);
        [DllImport("ClsApi.dll")]
        private static extern int getSerialNumber(byte[] pc8String);

        //   Read current device state
        //    T_ApiResult API_EXPORT getDeviceState(uint8_t *pu8State);
        [DllImport("ClsApi.dll")]
        private static extern int getDeviceState(ref byte pu8DeviceState);

        //    T_ApiResult API_EXPORT getHopperInventory(uint8_t u8Hopper, uint16_t *pu16NumberOfCoins);
        [DllImport("ClsApi.dll")]
        private static extern int getHopperInventory(byte u8Hopper, ref short pu16NumberOfCoins);

        //    T_ApiResult API_EXPORT lookupSystemEventCode(uint16_t u16Code, T_EventCategory *pu8Category, char pc8Description[]);
        [DllImport("ClsApi.dll")]
        private static extern int lookupSystemEventCode(short u16Code, ref byte pu8Category, byte[] pc8Description);

        //    T_ApiResult API_EXPORT lookupAcceptorEventCode(uint16_t u16Code, T_EventCategory *pu8Category, char pc8Description[]);
        [DllImport("ClsApi.dll")]
        private static extern int lookupAcceptorEventCode(short u16Code, ref byte pu8Category, byte[] pc8Description);

        //    T_ApiResult API_EXPORT lookupDispenserEventCode(uint16_t u16Code, T_EventCategory *pu8Category, char pc8Description[]);
        [DllImport("ClsApi.dll")]
        private static extern int lookupDispenserEventCode(short u16Code, ref byte pu8Category, byte[] pc8Description);

        //  T_ApiResult API_EXPORT getDenominationFromHopperNo(
        //      uint8_t u8HopperNo, char pc8ISO[], uint16_t *pu16Denom, char* pc8Mint);
        [DllImport("ClsApi.dll")]
        private static extern int getDenominationFromHopperNo(
            byte u8HopperNo, byte[] pc8ISO, ref short pu16Denom, ref byte pc8Mint);

        private static ClsApiClass mInstance = null;

        /// <summary>
        ///     constructor
        /// </summary>
        private ClsApiClass()
        {

        }

        /// <summary>
        ///     GetInstance
        /// </summary>
        /// <returns></returns>
        public static ClsApiClass GetInstance()
        {
            if  (mInstance == null)
            {
                mInstance = new ClsApiClass();
            }

            return  mInstance;
        }

        /// <summary>
        ///     Cls_OpenApi
        /// </summary>
        /// <returns></returns>
        public int Cls_OpenApi()
        {
            return  openApi();
        }

        /// <summary>
        ///     Cls_CloseApi
        /// </summary>
        /// <returns></returns>
        public int Cls_CloseApi()
        {
            return  closeApi();
        }

        /// <summary>
        ///     Cls_pollApiEvents
        /// </summary>
        /// <returns></returns>
        public int Cls_pollApiEvents(ref short pu16NumberOfNewEvents, int[] pu32Events)
        {
            return  pollApiEvents(ref pu16NumberOfNewEvents, pu32Events);
        }

        /// <summary>
        ///     Cls_pollSystemEvents
        /// </summary>
        /// <param name="pu16NumberOfNewEvents"></param>
        /// <param name="pu32Events"></param>
        /// <returns></returns>
        public int Cls_pollSystemEvents(ref short pu16NumberOfNewEvents, int[] pu32Events)
        {
            return  pollSystemEvents(ref pu16NumberOfNewEvents, pu32Events);
        }

        /// <summary>
        ///     Cls_pollAcceptorEvents
        /// </summary>
        /// <param name="pu16NumberOfNewEvents"></param>
        /// <param name="pu32Events"></param>
        /// <returns></returns>
        public int Cls_pollAcceptorEvents(ref short pu16NumberOfNewEvents, int[] pu32Events)
        {
            return  pollAcceptorEvents(ref pu16NumberOfNewEvents, pu32Events);
        }

        /// <summary>
        ///     Cls_pollDispenserEvents
        /// </summary>
        /// <param name="pu16NumberOfNewEvents"></param>
        /// <param name="pu32Events"></param>
        /// <returns></returns>
        public int Cls_pollDispenserEvents(ref short pu16NumberOfNewEvents, int[] pu32Events)
        {
            return  pollDispenserEvents(ref pu16NumberOfNewEvents, pu32Events);
        }

        /// <summary>
        ///     Cls_getConnectionStatus
        /// </summary>
        /// <returns></returns>
        public int Cls_getConnectionStatus(ref byte u8IsOnline)
        {
            return  getConnectionStatus(ref u8IsOnline);          
        }

        /// <summary>
        ///     Cls_emptyHoppers
        /// </summary>
        /// <param name="hopper"></param>
        /// <returns></returns>
        public int Cls_emptyHoppers(byte hopper)
        {
            return  emptyHoppers(hopper);
        }

        /// <summary>
        ///     Cls_getFirmwareVersion
        /// </summary>
        /// <param name="strVersion"></param>
        /// <returns></returns>
        public int Cls_getFirmwareVersion(byte[] strVersion)
        {
            return  getFirmwareVersions(strVersion);
        }

        /// <summary>
        ///     Cls_getFullSerialNumber
        /// </summary>
        /// <param name="strSerialNumber"></param>
        /// <param name="maxLength"></param>
        /// <returns></returns>
        public int Cls_getFullSerialNumber(byte[] strSerialNumber, int maxLength)
        {
            return  getFullSerialNumber(strSerialNumber, maxLength);
        }

        /// <summary>
        /// Cls_getSerialNumber
        /// </summary>
        /// <param name="strSerialNumber"></param>
        /// <returns></returns>
        public int Cls_getSerialNumber(byte[] strSerialNumber)
        {
            return  getSerialNumber(strSerialNumber);
        }

        /// <summary>
        ///     Cls_getDeviceState
        /// </summary>
        /// <param name="u8DeviceState"></param>
        /// <returns></returns>
        public int Cls_getDeviceState(ref byte u8DeviceState)
        {
            return getDeviceState(ref u8DeviceState);
        }

        /// <summary>
        ///     get Hopper Inventory
        /// </summary>
        /// <param name="u8Hopper"></param>
        /// <param name="pu16NumberOfCoins"></param>
        /// <returns></returns>
        public int Cls_getHopperInventory(byte u8Hopper, ref short pu16NumberOfCoins)
        {
            return  getHopperInventory(u8Hopper, ref pu16NumberOfCoins);
        }

        /// <summary>
        ///     get Online Hoppers
        /// </summary>
        /// <param name="pu8HoppersOnline"></param>
        /// <returns></returns>
        public int Cls_getOnlineHoppers(ref byte pu8HoppersOnline)
        {
            return  getOnlineHoppers(ref pu8HoppersOnline);
        }

        /// <summary>
        ///     Cls_lookupSystemEventCode
        /// </summary>
        /// <param name="u16Code"></param>
        /// <param name="pu8Category"></param>
        /// <param name="pc8Description"></param>
        /// <returns></returns>
        public int  Cls_lookupSystemEventCode(short u16Code, ref byte pu8Category, byte[] pc8Description)
        {
            return  lookupSystemEventCode(u16Code, ref pu8Category, pc8Description);
        }

        /// <summary>
        ///     Cls_lookupAcceptorEventCode
        /// </summary>
        /// <param name="u16Code"></param>
        /// <param name="u8Category"></param>
        /// <param name="pc8Description"></param>
        /// <returns></returns>
        public int Cls_lookupAcceptorEventCode(short u16Code, ref byte u8Category, byte[] pc8Description)
        {
            return  lookupAcceptorEventCode(u16Code, ref u8Category, pc8Description);
        }

        /// <summary>
        ///     Cls_lookupDispenserEventCode
        /// </summary>
        /// <param name="u16Code"></param>
        /// <param name="u8Category"></param>
        /// <param name="pc8Description"></param>
        /// <returns></returns>
        public int Cls_lookupDispenserEventCode(short u16Code, ref byte u8Category, byte[] pc8Description)
        {
            return  lookupDispenserEventCode(u16Code, ref u8Category, pc8Description);
        }

        /// <summary>
        ///     Cls_getDenominationFromHopperNo
        /// </summary>
        /// <param name="u8HopperNo"></param>
        /// <param name="pc8ISO"></param>
        /// <param name="pu16Denom"></param>
        /// <param name="pc8Mint"></param>
        /// <returns></returns>
        public int Cls_getDenominationFromHopperNo(
            byte u8HopperNo, byte[] pc8ISO, ref short pu16Denom, ref byte pc8Mint)
        {
            return getDenominationFromHopperNo(
                u8HopperNo, pc8ISO, ref pu16Denom, ref pc8Mint);
        }

        /// <summary>
        ///     Cls_dispenseAmount
        /// </summary>
        /// <param name="u32Amount"></param>
        /// <returns></returns>
        public int Cls_dispenseAmount(int u32Amount)
        {
            return  dispenseAmount(u32Amount);
        }

        /// <summary>
        ///     Cls_restartDevice
        /// </summary>
        /// <returns></returns>
        public int Cls_restartDevice()
        {
            return  restartDevice();
        }

        /// <summary>
        ///     Cls_AcceptAmount
        /// </summary>
        /// <param name="u32Amount"></param>
        /// <returns></returns>
        public int Cls_AcceptAmount(int u32Amount)
        {
            return  acceptAmount(u32Amount);
        }

        /// <summary>
        ///     Cls_dispenseFromHoppers
        /// </summary>
        /// <param name="u8NumbersOfCoins"></param>
        /// <returns></returns>
        public int Cls_dispenseFromHoppers(byte[] u8NumbersOfCoins)
        {
            return  dispenseFromHoppers(u8NumbersOfCoins);
        }
    }
}
